import React, { useEffect, useState } from "react";
import { message } from "antd";
import {
  giveRequest,
  getbusinfo,
  getstationinfo,
  getlinedata,
  getlineinfo,
  modifybusinfo,
  modifystationinfo,
} from "../../lib/apiconfig";

const REFRESH_RATE = 30 * 1000;  // 刷新时间间隔（毫秒）
const TIME_GAP = 7200;  // 刷新时间对于真实时间的间隔（秒）
const TIME_RATE = TIME_GAP / 3600;  // 刷新时间对于真实时间的一个小时的比率
const MAX_NEW_WAITING_NUMBER = 10;  // 最大新增等待人数
const MAX_SPEED = 60;  // 公交车最大时速

const ld_data = [
  {
    longitude: 118.752746, 
    dimensionality: 36.716443
  },
  {
    longitude: 118.907727, 
    dimensionality: 36.662841
  },
  {
    longitude: 118.95674,
    dimensionality: 36.752525
  }
];

/**
 * @description 随机过程，用于更新公交和站点的数据
 */
const RandomProcess = () => {
  const [freshAction, setFreshAction] = useState(false);

  useEffect(() => {
    giveRequest(getbusinfo(0,1000), "GET", null, busInfoRes => {
      const status = busInfoRes.status;
      if ( status === "fail" ) {
        message.error("获取数据失败!");
      } else {
        giveRequest(getstationinfo(0,1000), "GET", null, stationInfoRes => {
          const status = stationInfoRes.status;
          if ( status === "fail" ) {
            message.error("获取数据失败!");
          } else {
            giveRequest(getlineinfo(0, 1000), "GET", null, lineInfoRes => {
              const status = lineInfoRes.status;
              if ( status === "fail" ) {
                message.error("获取数据失败!");
              } else {
                giveRequest(getlinedata, "GET", null, lineDataRes => {
                  const status = lineDataRes.status;
                  if ( status === "fail" ) {
                    message.error("获取数据失败!");
                  } else {
                    sendNewBus(busInfoRes.data, lineInfoRes.data);
                    stopBus(busInfoRes.data, lineInfoRes.data);
                    updateData(busInfoRes.data, stationInfoRes.data, lineDataRes.data);
                    setTimeout(() => {
                      console.log("refresh!!!");
                      setFreshAction(!freshAction);
                    }, REFRESH_RATE);
                  }
                });
              }
            });
          }
        });
      }
    });
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [freshAction]);

  // 公交调度函数
  const sendNewBus = (busData, lineInfo) => {
    var sendBus = [];
    var check = [];

    lineInfo.forEach(line => {
      check[line.id] = 0;
      line.station.forEach(station => {
        if ( check[line.id] === 0 && station.waitingnumber > 20 ) {
          busData.forEach(bus => {
            if ( bus.lineid === line.id && bus.runningcondition === 0 && bus.faultcondition === 0 ) {
              sendBus.push({
                licence: bus.licence,
                stationid: station.stationid,
              });
              check[line.id] = 1;
            }
          });
        }
      });
    });

    if ( sendBus.length > 0 ) {
      sendBus.forEach(bus => {
        giveRequest(
          modifybusinfo,
          "POST",
          {
            status: "modifybusinfo",
            data: {
              licence: bus.licence,
              runningcondition: 1,
            }
          },
          res => {
            if ( res.status === "success" ) {
              giveRequest(
                modifystationinfo,
                "POST",
                {
                  status: "modifystationinfo",
                  data: {
                    id: bus.stationid,
                    waitingnumber: 10,
                  }
                },
                res => {
                  if ( res.status === "success"  ){
                    console.log("新发车辆: " + bus.licence);
                    console.log("修改站点: " + bus.stationid);
                  }
                }
              )
            }
          }
        );
      });
    }
  }

  // 停止车辆
  const stopBus = (busData, lineInfo) => {
    var keys = [];
    var check = [];
    var stationID = [];

    lineInfo.forEach(line => {
      keys[line.id] = 0;
      check[line.id] = 0;
      line.station.forEach(station => {
        if ( station.waitingnumber > 5 )
          keys[line.id] = 1;
        else
          stationID[line.id] = station.stationid;
      });
    });

    busData.forEach(bus => {
      if ( bus.runningcondition === 1 && bus.faultcondition === 0 && keys[bus.lineid] === 0 ) {
        if ( check[bus.lineid] === 0 ) {
          check[bus.lineid] = 1;
        } else if ( check[bus.lineid] === 1 ) {
          giveRequest(
            modifybusinfo,
            "POST",
            {
              status: "modifybusinfo",
              data: {
                licence: bus.licence,
                runningcondition: 0,
                speed: 0,
                busload: 0,
                pindex: 0,
                longitude: bus.lineid <= 3 && bus.lineid >= 1 ? ld_data[bus.lineid-1].longitude : ld_data[2].longitude,
                dimensionality: bus.lineid <= 3 && bus.lineid >= 1 ? ld_data[bus.lineid-1].dimensionality : ld_data[2].dimensionality,
              }
            },
            res => {
              if ( res.status === "success" ) {
                giveRequest(
                  modifystationinfo,
                  "POST",
                  {
                    status: "modifystationinfo",
                    data: {
                      id: stationID[bus.lineid],
                      waitingnumber: 10,
                    }
                  },
                  res => {
                    if ( res.status === "success" ) {
                      console.log("停发车辆: " + bus.licence);
                      console.log("修改站点: " + stationID[bus.lineid]);
                    }
                  }
                )
              }
            }
          )
          check[bus.lineid] = 2;
        }
      }
    });
  }

  const calcDistance = (firstLongitude, firstDimensionality, secondLongitude, secondDimensionality) => {
    var x = (secondLongitude - firstLongitude) * 111322.2222 * Math.cos(firstDimensionality);
    var y = (secondDimensionality - firstDimensionality) * 111136.1111;
    var d = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
    return d;
  };

  const updateData = (busData, stationData, lineData) => {
    var longitude = null;
    var dimensionality = null;
    var speed = null;
    var pindex = null;
    var busload = null;
    var maxload = null;
    var distance = null;
    var linePointData = null;
    var PDataLength = null;
    var d = 0.0;
    var delta_d = 0;
    var currentPointIndex = null;
    var nextPointIndex = null;
    var current_longitude = null;
    var current_dimensionality = null;
    var next_point = null;
    var next_longitude = null;
    var next_dimensionality = null;
    var get_off_number = null;
    var get_on_number = null;

    busData.forEach(bus => {
      if ( bus.faultcondition === 0 && bus.runningcondition === 1 && bus.lineid ) {
        longitude = bus.longitude;
        dimensionality = bus.dimensionality;
        speed = bus.speed;
        pindex = bus.pindex;
        busload = bus.busload;
        maxload = bus.maxload;
        distance = speed * TIME_RATE;
        lineData.forEach(line => {
          if ( line.id === bus.lineid ) {
            linePointData = line.data;
            PDataLength = linePointData.length;

            d = 0.0;
            delta_d = 0;
            currentPointIndex = pindex;
            nextPointIndex = (currentPointIndex + 1) % (2 * PDataLength);
            current_longitude = longitude;
            current_dimensionality = dimensionality;
            next_point = nextPointIndex < PDataLength ? linePointData[nextPointIndex] : linePointData[nextPointIndex-PDataLength];
            next_longitude = nextPointIndex < PDataLength ? linePointData[nextPointIndex].longitude : linePointData[nextPointIndex-PDataLength].longitude;
            next_dimensionality = nextPointIndex < PDataLength ? linePointData[nextPointIndex].dimensionality : linePointData[nextPointIndex-PDataLength].dimensionality;

            while ( true ) {
              delta_d = calcDistance(current_longitude, current_dimensionality, next_longitude, next_dimensionality);

              if ( d + delta_d > distance) {
                // longitude = (distance - d) / delta_d * (next_longitude - current_longitude) + current_longitude;
                // dimensionality = (distance - d) / delta_d * (next_dimensionality - current_dimensionality) + current_dimensionality;
                longitude = next_longitude;
                dimensionality = next_dimensionality;
                pindex = nextPointIndex;
                speed = parseInt(Math.random() * MAX_SPEED);

                giveRequest(
                  modifybusinfo,
                  "POST",
                  {
                    status: "modifybusinfo",
                    data: {
                      licence: bus.licence,
                      busload: busload,
                      runningcondition: 1,
                      speed: speed,
                      longitude: longitude,
                      dimensionality: dimensionality,
                      pindex: pindex,
                    }
                  },
                  res => {
                    if ( res.status === "success" ) {
                      console.log("车辆 " + res.data.licence + " 更新成功");
                      console.log(res.data ? "车载人数: " + res.data.busload + "; 速度: " + res.data.speed : "error");
                    }
                  }
                );

                break;
              } else {
                if ( next_point.si ) {
                  // eslint-disable-next-line no-loop-func
                  stationData.forEach(station => {
                    if ( station.id === next_point.si ) {
                      get_off_number = parseInt(Math.random() * busload);
                      busload = busload - get_off_number;
                      get_on_number = parseInt(Math.random() * station.waitingnumber);
                      get_on_number = get_on_number > maxload - busload ? maxload - busload : get_on_number;
                      busload = busload + get_on_number;

                      giveRequest(
                        modifystationinfo,
                        "POST",
                        {
                          status: "modifystationinfo",
                          data: {
                            id: station.id,
                            waitingnumber: station.waitingnumber - get_on_number + parseInt(Math.random() * MAX_NEW_WAITING_NUMBER),
                          }
                        },
                        res => {
                          if ( res.status === "success" ) {
                            console.log("站点 " + station.id + " 更新成功");
                            console.log("等待人数: " + (res.data ? res.data.waitingnumber : "error"));
                          }
                        }
                      );
                    }
                  });
                }

                currentPointIndex = nextPointIndex;
                nextPointIndex = (currentPointIndex + 1) % (2 * PDataLength);
                current_longitude = currentPointIndex < PDataLength ? linePointData[currentPointIndex].longitude : linePointData[currentPointIndex-PDataLength].longitude;
                current_dimensionality = currentPointIndex < PDataLength ? linePointData[currentPointIndex].dimensionality : linePointData[currentPointIndex-PDataLength].dimensionality;
                next_point = nextPointIndex < PDataLength ? linePointData[nextPointIndex] : linePointData[nextPointIndex-PDataLength];
                next_longitude = nextPointIndex < PDataLength ? linePointData[nextPointIndex].longitude : linePointData[nextPointIndex-PDataLength].longitude;
                next_dimensionality = nextPointIndex < PDataLength ? linePointData[nextPointIndex].dimensionality : linePointData[nextPointIndex-PDataLength].dimensionality;
                d = d + delta_d;
              }
            }
          }
        });
      }
    });
  };

  return (
    <div style={{ display: "none" }}></div>
  );
}

export default RandomProcess;